package com.cictec.middleware.gps.engine.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.cictec.middleware.commons.utils.Constants;
import com.cictec.middleware.commons.utils.DateUtils;
import com.cictec.middleware.commons.utils.MapBeanUtils;
import com.cictec.middleware.core.pojo.ESEnterOutEntity;
import com.cictec.middleware.feign.elasticsearch.MiddlewareElasticsearchService;
import com.cictec.middleware.gps.engine.BusInstance;
import com.cictec.middleware.gps.engine.TimingPoint;

/**
 * 进出站处理
 * @author Administrator
 *
 */
@Component
public class DataStorageEnterOutService {

	private static Logger logger = LoggerFactory.getLogger(DataStorageEnterOutService.class);
	
	@Autowired
	private StringRedisTemplate stringRedisTemplate;
	@Autowired
	private MiddlewareElasticsearchService middlewareElasticsearchService;
	
	/**
	 * 进出站信息 保存至 Elasticsearch中， 进出站 为一条数据
	 * <br> redisKey --> 【bus-enterOutStation】
	 * @param busInstance
	 */
	public void saveEnterOutToES(BusInstance busInstance) {
		if(!busInstance.isEnterOut()){
			return;
		}
		
		String redisKey = "bus-enterOutStation";
		TimingPoint point = busInstance;
		String currentTime = String.valueOf(point.getTime().getTime());

		// 进出站信息 保存至 Elasticsearch中， 进出站 为一条数据
		String busEnterOutStatus = point.getStationEnterOut();
		String currentStatSeq = point.getStationLineSeqOrg();
		String lineUuid = point.getLineUuid();
		String lineType = point.getStationLineTypeOrg();
		String busUuid = point.getBusUuid();
			
		HashOperations<String, String, String> ops = stringRedisTemplate.opsForHash();
		if(point.isInStation()){
			/* ************  判定是否是上一站信息 start ***************************************/
			if(ops.hasKey(redisKey, busUuid)){
				String json = ops.get(redisKey, busUuid);
				ESEnterOutEntity preEntity = JSON.parseObject(json, ESEnterOutEntity.class);
				
				String tmp_line_uuid = preEntity.getLine_uuid();
				String tmp_line_type = preEntity.getLine_type();
				String tmp_station_sequence = preEntity.getStation_sequence();
				
				if(!tmp_line_uuid.equals(lineUuid)
						|| !tmp_line_type.equals(lineType)
						|| !tmp_station_sequence.equals(currentStatSeq)){
					
					// 保存上一个不同站点进出站信息
					saveEnterOutToES(preEntity);
					stringRedisTemplate.opsForHash().delete(redisKey, busUuid);
				}
			}
			/* ************  判定是否是上一站点信息 end ***************************************/
				
			// 【进站】
			ESEnterOutEntity entity =covtertEnterOut(point, true);
			stringRedisTemplate.opsForHash().put(redisKey, busUuid, JSON.toJSONString(entity));
			
		} else if (busEnterOutStatus.equals(Constants.VAL_ENTER_OUT_SATION_OUT)) {
			if(ops.hasKey(redisKey, busUuid)){
				String json = ops.get(redisKey, busUuid);
				ESEnterOutEntity preEntity = JSON.parseObject(json, ESEnterOutEntity.class);
				
				String tmp_line_uuid = preEntity.getLine_uuid();
				String tmp_line_type = preEntity.getLine_type();
				String tmp_station_sequence = preEntity.getStation_sequence();
				
				if(!tmp_line_uuid.equals(lineUuid)
						|| !tmp_line_type.equals(lineType)
						|| !tmp_station_sequence.equals(currentStatSeq)){
					// 保存上一个不同站点进出站信息
					saveEnterOutToES(preEntity);
				
					// 【出站】
					ESEnterOutEntity entity = covtertEnterOut(point, false);
					saveEnterOutToES(entity);
				}else{
					preEntity.setOut_time(currentTime);
					preEntity.setOut_speed(point.getSpeed());
					if(point.containsAttribute(Constants.LINE_STATION_TRIGGER_TYPE)){
						preEntity.setTrigger_type(point.getStationEnterOutTrigger());// 触发类型（0：表示自动触发 1：表示手动触发 2：表示调试数据 3:wifi 报站类型 ）
					}
					
					saveEnterOutToES(preEntity);
				}
				
			}else{
				// 【出站】
				ESEnterOutEntity entity = covtertEnterOut(point, false);
				saveEnterOutToES(entity);
			}
			
			// 出站删除缓存
			stringRedisTemplate.opsForHash().delete(redisKey, busUuid);
		}
	}
	
	/**
	 * 进出站存储到es中
	 * @param entity
	 */
	private void saveEnterOutToES(ESEnterOutEntity entity){

		logger.debug("进出站存储到es中：" + JSON.toJSONString(entity));
		middlewareElasticsearchService.saveRealCaculateEnterOutStation(MapBeanUtils.java2Map(entity));
		
	}
	
	// 进出站临时存储值
	private Map<String, ESEnterOutEntity> enterOutMap = new HashMap<String, ESEnterOutEntity>();
	public List<ESEnterOutEntity> getEnterOutData(List<TimingPoint> points) {
			
		if (points == null || points.size() == 0) {
			logger.error("没有进出站信息");
			return new ArrayList<ESEnterOutEntity>();
		}
			
		// 过滤掉多次出站的情况
//		List<TimingPoint> _points = new ArrayList<TimingPoint>();
//		if(points.size() > 2){
//			for (int i = 1; i < points.size(); i++) {
//				TimingPoint prePoint = points.get(i-1);
//				TimingPoint currentPoint = points.get(i);
//				if(!prePoint.isEnterOut() && !currentPoint.isEnterOut()){
//					
//				}else{
//				}
//			
//			}
//		}
		
		List<ESEnterOutEntity> dataList = new ArrayList<ESEnterOutEntity>();
		for (TimingPoint point : points) {
			String currentTime = String.valueOf(point.getTime().getTime());

			// 进出站信息 保存至 Elasticsearch中， 进出站 为一条数据
			String busEnterOutStatus = point.getStationEnterOut();
			String currentStatSeq = point.getStationLineSeqOrg();
			String lineUuid = point.getLineUuid();
			String lineType = point.getStationLineTypeOrg();
			String busUuid = point.getBusUuid();
				

			if(point.isInStation()){
				/* ************  判定是否是上一站信息 start ***************************************/
				if(enterOutMap.containsKey(busUuid)){
					ESEnterOutEntity preEntity = enterOutMap.get(busUuid);
					
					String tmp_line_uuid = preEntity.getLine_uuid();
					String tmp_line_type = preEntity.getLine_type();
					String tmp_station_sequence = preEntity.getStation_sequence();
					
					if(!tmp_line_uuid.equals(lineUuid)
							|| !tmp_line_type.equals(lineType)
							|| !tmp_station_sequence.equals(currentStatSeq)){
						
						// 保存上一个不同站点进出站信息
						dataList.add(preEntity);
						enterOutMap.remove(point.getBusUuid());
					}
				}
				/* ************  判定是否是上一站点信息 end ***************************************/
					
				// 【进站】
				ESEnterOutEntity entity =covtertEnterOut(point, true);
				enterOutMap.put(point.getBusUuid(), entity);
				
			} else if (busEnterOutStatus.equals(Constants.VAL_ENTER_OUT_SATION_OUT)) {
				if(enterOutMap.containsKey(busUuid)){
					ESEnterOutEntity preEntity = enterOutMap.get(busUuid);
					
					String tmp_line_uuid = preEntity.getLine_uuid();
					String tmp_line_type = preEntity.getLine_type();
					String tmp_station_sequence = preEntity.getStation_sequence();
					
					if(!tmp_line_uuid.equals(lineUuid)
							|| !tmp_line_type.equals(lineType)
							|| !tmp_station_sequence.equals(currentStatSeq)){
						// 保存上一个不同站点进出站信息
						dataList.add(preEntity);
					
						// 【出站】
						ESEnterOutEntity entity = covtertEnterOut(point, false);
						dataList.add(entity);
					}else{
						preEntity.setOut_time(currentTime);
						preEntity.setOut_speed(point.getSpeed());
						if(point.containsAttribute(Constants.LINE_STATION_TRIGGER_TYPE)){
							preEntity.setTrigger_type(point.getStationEnterOutTrigger());// 触发类型（0：表示自动触发 1：表示手动触发 2：表示调试数据 3:wifi 报站类型 ）
						}
						
						dataList.add(preEntity);
					}
					
				}else{
					// 【出站】
					ESEnterOutEntity entity = covtertEnterOut(point, false);
					dataList.add(entity);
				}
				
				// 出站删除缓存
				enterOutMap.remove(point.getBusUuid());
			}
		}
		
		return dataList;
	}
	
	private ESEnterOutEntity covtertEnterOut(TimingPoint point, boolean isInStation){
		String currentTime = String.valueOf(point.getTime().getTime());
		
		ESEnterOutEntity entity = new ESEnterOutEntity();
		entity.setDate(DateUtils.formatDate(point.getTime()));
		entity.setBus_uuid(point.getBusUuid());
		entity.setBus_plate_number(point.getBusNumber());
		entity.setLine_uuid(point.getLineUuid());
		entity.setLine_name(point.getLineName());
		entity.setLine_type(point.getStationLineTypeOrg());
		
		entity.setLs_uuid(point.getStationUuidOrg());
		entity.setStation_name(point.getStationNameOrg());
		entity.setStation_sequence(point.getStationLineSeqOrg());
		
		if(isInStation){
			entity.setEnter_time(currentTime);
			entity.setEnter_speed(point.getSpeed());
		}else{
			entity.setOut_time(currentTime);
			entity.setOut_speed(point.getSpeed());
			
		}
		entity.setDrv_iccard(point.getDriverIccard());
		entity.setDrv_name(point.getDriverName());
		if(point.containsAttribute(Constants.LINE_STATION_TRIGGER_TYPE)){
			entity.setTrigger_type(point.getStationEnterOutTrigger());// 触发类型（0：表示自动触发 1：表示手动触发 2：表示调试数据 3:wifi 报站类型 ）
		}
		
		return entity;
	}
}
